//
// Created by 麻再挺 on 2021/1/19.
//
#include "linear_list_menu.h"

// 线性表实现
void linear_list_impl();

// 线性链表实现
void linked_list_impl();

// 单向循环链表实现
void circular_linked_list_impl();

// 双向链表
void double_linked_list_impl();


// 线性表运行主函数
void linear_list_run() {
    // 菜单
    int menu = -1;
    // 是否运行
    Status is_run = TRUE;
    while (is_run) {
        printf("╔═══════════════════════════════════════════════╗\n");
        printf("║                     线性表                    ║\n");
        printf("║ 1: 线性表实现                                 ║\n");
        printf("║ 2: 线性链表实现                               ║\n");
        printf("║ 3: 循环链表实现                               ║\n");
        printf("║ 4: 双向链表实现                               ║\n");
        printf("║ 0: 退出                                       ║\n");
        printf("╚═══════════════════════════════════════════════╝\n");
        printf("请选择功能菜单: ");
        fflush(stdout);
        scanf("%d", &menu);

        switch (menu) {
            case 0:
                // 退出
                is_run = FALSE;
                break;
            case 1:
                linear_list_impl();
                break;
            case 2:
                linked_list_impl();
                break;
            case 3:
                circular_linked_list_impl();
                break;
            case 4:
                double_linked_list_impl();
                break;
            default:
                printf("输入异常\n");
                break;
        }
    }
}

/**
 * 比较数值大小
 * @param a 第一个数
 * @param b 第二个数
 * @return 1: 相等; 0: 不等
 */
Status compare(ElemType a, ElemType b) {
    return a == b;
}

// 线性表实现
void linear_list_impl() {
    LinearList list;
    // 初始化
    Status res = Linear_List_Init(&list);
    if (res != OK) {
        printf("初始化异常\n");
        return;
    }
    printf("初始化列表: ");
    Linear_List_Print(&list);
    // 添加数据
    for (int i = 0; i < 10; i++) {
        Linear_List_Push(&list, (ElemType) (10 + i));
    }
    printf("push添加数据: ");
    Linear_List_Print(&list);
    // 指定位置插入数据
    res = Linear_List_Insert(&list, 6, (ElemType) 2);
    if (res != OK) {
        printf("插入异常\n");
        return;
    }
    printf("insert向索引位置6插入数据: ");
    Linear_List_Print(&list);

    // 将最后一个元素删除
    Linear_List_Pop(&list);

    printf("pop删除数据: ");
    Linear_List_Print(&list);
    // 删除索引为 6 的元素
    res = Linear_List_Delete(&list, 6);
    if (res != OK) {
        printf("删除异常\n");
        return;
    }
    printf("delete删除索引为6的数据: ");
    Linear_List_Print(&list);
    // 查找列表中是否存在元素14
    int index = Linear_List_Locate_Elem(&list, 19, compare);
    if (index == -1) {
        printf("元素 14 不在当前列表中\n");
    } else {
        printf("元素 14 所在索引: %d\n", index);
    }
    // 线性表合并
    LinearList list2, list3;
    // 初始化列表2
    Linear_List_Init(&list2);
    // 向列表2中添加数据
    for (int i = 0; i < 10; ++i) {
        Linear_List_Push(&list2, 3 * i);
    }
    printf("列表2中数据为: ");
    Linear_List_Print(&list2);
    // 合并数据
    Linear_List_Merge(&list, &list2, &list3);
    printf("合并后列表list3中数据为: ");
    Linear_List_Print(&list3);

    // 判断列表是否为空
    res = Linear_List_Empty(&list);
    if (res == TRUE) {
        printf("列表为空\n");
    } else {
        printf("列表不为空\n");
    }

    // 获取列表长度
    int length = Linear_List_Length(&list);
    printf("列表 list 长度为: %d\n", length);

    // 根据索引获取结点数据
    ElemType elem;
    Linear_List_Get_Elem(&list, 6, &elem);
    printf("列表第 6 个元素值为: %d\n", elem);
}

// 线性链表实现
void linked_list_impl() {
    // 声明链表
    LinkedList list;
    // 创建链表
    Status res = Linked_List_Create(&list);
    if (res != OK) {
        printf("创建链表异常\n");
        return;
    }
    printf("初始化链表: ");
    Linked_List_Print(&list);
    // 添加数据
    for (int i = 0; i < 10; i++) {
        Linked_List_Push(&list, (ElemType) (10 + i));
    }
    printf("push添加数据: ");
    Linked_List_Print(&list);

    // 指定位置插入数据
    res = Linked_List_Insert(&list, 6, (ElemType) 2);
    if (res != OK) {
        printf("插入异常\n");
        return;
    }
    printf("insert向索引位置6插入数据: ");
    Linked_List_Print(&list);

    // 将最后一个元素删除
    Linked_List_Pop(&list);
    printf("pop删除数据: ");
    Linked_List_Print(&list);

    // 删除索引为 6 的元素
    res = Linked_List_Delete(&list, 6);
    if (res != OK) {
        printf("删除异常\n");
        return;
    }
    printf("delete删除索引为6的数据: ");
    Linked_List_Print(&list);

    // 数据
    LinkedList node;
    // 获取索引为 6 的元素
    res = Linked_List_Get_Elem(&list, 6, &node);
    if (res != OK) {
        printf("获取索引为 6 的数据失败\n");
        return;
    }
    printf("getElem获取索引为6的数据: %d\n", node.data);

    // 两个链表合并
    LinkedList list2;
    // 初始化
    Linked_List_Create(&list2);
    // 添加数据
    for (int i = 0; i < 10; i++) {
        Linked_List_Push(&list2, (ElemType) 3 * i + 1);
    }
    // 合并
    res = Linked_List_Merge(&list, &list2);
    if (res != OK) {
        printf("合并链表数据失败\n");
        return;
    }
    printf("merge合并后数据: ");
    Linked_List_Print(&list);

}

// 单向循环链表实现
void circular_linked_list_impl() {
    // 声明链表
    CLinkedList list;
    // 创建链表
    Status res = CLinked_List_Create(&list);
    if (res != OK) {
        printf("创建链表异常\n");
        return;
    }
    printf("初始化链表: ");
    CLinked_List_Print(&list);

    // 添加数据
    for (int i = 0; i < 10; i++) {
        CLinked_List_Push(&list, (ElemType) (10 + i));
    }
    printf("push添加数据: ");
    CLinked_List_Print(&list);

    // 指定位置插入数据
    res = CLinked_List_Insert(&list, 6, (ElemType) 2);
    if (res != OK) {
        printf("插入异常\n");
        return;
    }
    printf("insert向索引位置6插入数据: ");
    CLinked_List_Print(&list);

    // 将最后一个元素删除
    CLinked_List_Pop(&list);
    printf("pop删除数据: ");
    CLinked_List_Print(&list);

    // 删除索引为 6 的元素
    res = CLinked_List_Delete(&list, 6);
    if (res != OK) {
        printf("删除异常\n");
        return;
    }
    printf("delete删除索引为6的数据: ");
    CLinked_List_Print(&list);

    // 数据
    CLinkedList node;
    // 获取索引为 6 的元素
    res = CLinked_List_Get_Elem(&list, 6, &node);
    if (res != OK) {
        printf("获取索引为 6 的数据失败\n");
        return;
    }
    printf("getElem获取索引为6的数据: %d\n", node.data);

    // 两个链表合并
    CLinkedList list2;
    // 初始化
    CLinked_List_Create(&list2);
    // 添加数据
    for (int i = 0; i < 10; i++) {
        CLinked_List_Push(&list2, (ElemType) 3 * i + 1);
    }
    // 合并
    res = CLinked_List_Merge(&list, &list2);
    if (res != OK) {
        printf("合并链表数据失败\n");
        return;
    }
    printf("merge合并后数据: ");
    CLinked_List_Print(&list);
}

// 双向链表实现
void double_linked_list_impl() {
    // 声明链表
    DLinkedList list;
    // 创建链表
    Status res = DLinked_List_Create(&list);
    if (res != OK) {
        printf("创建链表异常\n");
        return;
    }
    printf("初始化链表: ");
    DLinked_List_Print(&list);

    // 添加数据
    for (int i = 0; i < 10; i++) {
        DLinked_List_Push(&list, (ElemType) (10 + i));
    }
    printf("push添加数据: ");
    DLinked_List_Print(&list);

    // 指定位置插入数据
    res = DLinked_List_Insert(&list, 6, (ElemType) 2);
    if (res != OK) {
        printf("插入异常\n");
        return;
    }
    printf("insert向索引位置6插入数据: ");
    DLinked_List_Print(&list);

    // 将最后一个元素删除
    DLinked_List_Pop(&list);
    printf("pop删除数据: ");
    DLinked_List_Print(&list);

    // 删除索引为 6 的元素
    res = DLinked_List_Delete(&list, 6);
    if (res != OK) {
        printf("删除异常\n");
        return;
    }
    printf("delete删除索引为6的数据: ");
    DLinked_List_Print(&list);

    // 数据
    DLinkedList node;
    // 获取索引为 6 的元素
    res = DLinked_List_Get_Elem(&list, 6, &node);
    if (res != OK) {
        printf("获取索引为 6 的数据失败\n");
        return;
    }
    printf("getElem获取索引为6的数据: %d\n", node.data);

    // 两个链表合并
    DLinkedList list2;
    // 初始化
    DLinked_List_Create(&list2);
    // 添加数据
    for (int i = 0; i < 10; i++) {
        DLinked_List_Push(&list2, (ElemType) 3 * i + 1);
    }
    // 合并
    res = DLinked_List_Merge(&list, &list2);
    if (res != OK) {
        printf("合并链表数据失败\n");
        return;
    }
    printf("merge合并后数据: ");
    DLinked_List_Print(&list);
}

#pragma clang diagnostic pop